package openjdk.jdk.nio;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;

/**
 * Created by boot on 1/14/16.
 */
public class BufferToText {
    private static final String fileName = "testFile.txt";

    public static void main(String[] args) {
        try {
            // 依照系统默认的编码方式写文件
            FileChannel fc = new FileOutputStream(fileName).getChannel();
            fc.write(ByteBuffer.wrap("丹东字符".getBytes()));
            fc.close();

            // 读文本
            fc = new FileInputStream(fileName).getChannel();

            ByteBuffer buf = ByteBuffer.allocate(1024);
            fc.read(buf);
            buf.flip();
            // 显示乱码，采用默认的编码方式(UTF-16BE)将ByteBuffer转换成CharBuffer
            System.out.println(buf.asCharBuffer());

            buf.rewind();   // 准备重读

            // 当前系统的默认编码方式
            String encoding = System.getProperty("file.encoding");
            // 使用系统默认的编码方式将ByteBuffer转换成CharBuffer
            System.out.println("Decoded using " + encoding + ":" + Charset.forName(encoding).decode(buf));
            fc.close();


            System.out.println("===================== 第二种方式 ===================");
            // 先以UTF-16BE编码后再写文件
            fc = new FileOutputStream(fileName).getChannel();
            fc.write(ByteBuffer.wrap("测试字符".getBytes("UTF-16BE")));
            fc.close();
            // 再尝试读
            fc = new FileInputStream(fileName).getChannel();
            buf.clear();
            fc.read(buf);
            buf.flip(); // 重置指针到开头

            // 显示正常，可见到asCharBuffer()方式是以UTF-16BE解码的
            System.out.println(buf.asCharBuffer());
            fc.close();


            System.out.println("===================== 第三种方式 =================");
            // 直接通过CharBuffer写
            fc = new FileOutputStream(fileName).getChannel();
            buf = ByteBuffer.allocate(8);  // UTF-16编码每个字符占二个字节，4个字符要8个字节
            // 将ByteBufer转换成CharBuffer后再写
            buf.asCharBuffer().put("测试字叁");
            fc.write(buf);
            fc.close();

            // 读并显示
            fc = new FileInputStream(fileName).getChannel();
            buf.clear();
            fc.read(buf);
            buf.flip();
            // 同时也采用默认的转换方式(UTF-16BE) asCharBuffer将ByteBuffer转换成CharBuffer
            System.out.println(buf.asCharBuffer());
            fc.close();

            copyFile(fileName, "copyOfSrc.txt");


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 拷贝文件
     *
     * @param src  源文件
     * @param dest 目标文件
     */
    public static void copyFile(String src, String dest) throws IOException {
        RandomAccessFile raf = new RandomAccessFile(src, "r");
        FileChannel srcFileChannel = raf.getChannel();
        RandomAccessFile rafDest = new RandomAccessFile(dest, "rw");
        FileChannel destFileChannel = rafDest.getChannel();

        long position = 0;
        long cnt = srcFileChannel.size();
        srcFileChannel.transferTo(position, cnt, destFileChannel);

    }
}
